package org.libarae.server;

import org.libarae.server.exceptions.ConfigParseException;

/**
 * @author Tyler Holzer
 *
 * ServerConfig.java -- a part of Libarae
 * contains configuration data required to properly run the server
 */
public class ServerConfig {
	//actual server data
	/**
	 * specifies the database type
	 * Values are either 0 for sqlite or 1 for mySql
	 */
	private int databaseType; 
	/**
	 * specifies if a database has been created or not
	 */
	private boolean databaseExists; 
	/**
	 * the port that the server should run on
	 */
	private int port;
	/**
	 * Specifies whether a password is required
	 */
	private boolean passwordRequired;
	/**
	 * specifies whether a image folder has been created
	 */
	private boolean imagesFolderExists;
	/**
	 * Contains the access key for ISBNdb
	 */
	private String ISBNdbAccessKey;
	/**
	 * marks if the server is in debugMode
	 */
	private boolean debugMode;
	
	//used to make sure all values have been filled
	/**
	 * marks if an invalid data value was found in the XML
	 */
	private boolean xmlError;
	/**
	 * marks if the databaseType has been set yet
	 */
	private boolean dbTypeSet;
	/**
	 * marks if the databaseExists has been set yet
	 */
	private boolean dbExistsSet;
	/**
	 * mark if imageFolderExists has been set yet
	 */
	private boolean imagesFolderExistsSet;
	/**
	 * mark if ISBNdbAccessKey has been set yet
	 */
	private boolean ISBNdbAccessKeySet;
	
	/*
	 * Constructor
	 */
	/**
	 * set all errors to false, and set the prot to 80
	 */
	public ServerConfig() {
		port=80; //Port defaultly 80, only through advanced editing of the config file can it be changed
		//No errors, and nothing has been set
		xmlError=false;
		dbTypeSet=false;
		dbExistsSet=false;
		passwordRequired=false;
		imagesFolderExistsSet=false;
		ISBNdbAccessKeySet=false;
		debugMode=false;
	}
	
	/**
	 * returns the database type
	 * values - 0 for sqlite
	 * 			1 for mysql
	 * 			2 for oracle
	 * @return int
	 */
	public int getDBType() {
		return databaseType;
	}
	
	/**
	 * Sets the Database type
	 * 
	 * @param type - the type of DB
	 */
	public void setDBType(int type) {
		//if unknown value, set throw an XML error
		if(type < 0||type>2) {
			xmlError=true;
			return;
		}
		dbTypeSet=true;
		databaseType=type;
	}
	
	/**
	 * sets if the database exists
	 * 
	 * @param exists  - int set to 0 for false, 1 for true, or anything else for an XMLerror
	 */
	public void setDBExists(int exists) {
		switch(exists) {
			case 0:
				dbExistsSet=true;
				databaseExists=false;
				break;
			case 1:
				dbExistsSet=true;
				databaseExists=true;
				break;
			default:
				xmlError=true; // unkown value, throw error
				break;
		}
	}
	
	/**
	 * returns if the database exists
	 * 
	 * @return boolean
	 */
	public boolean getDBExists() {
		return databaseExists;
	}
	
	/**
	 * used to verify that no issues occurred while reading the config file
	 * returns false if no error occurred, throws an exception specifying the type of exception if not
	 * 
	 * @return boolean
	 * @throws ConfigParseException
	 */
	public boolean configError() throws ConfigParseException {
		if(xmlError){
			throw new ConfigParseException(ConfigParseException.INVALID_ARGUMENT_IN_XML);
		}
		if(!dbTypeSet){
			throw new ConfigParseException(ConfigParseException.DATABASE_TYPE_NOT_SET);
		}
		if(!dbExistsSet){
			throw new ConfigParseException(ConfigParseException.DATABASE_EXISTANCE_NOT_SPECIFIED);
		}
		if(!imagesFolderExistsSet)
			throw new ConfigParseException(ConfigParseException.IMAGE_FOLDER_EXISTANCE_NOT_SPECIFIED);
		if(!this.ISBNdbAccessKeySet)
			throw new ConfigParseException(ConfigParseException.ISBNDB_ACCESS_KEY_NOT_SET);
		//if no errors return false
		return false;
	}
	
	/**
	 * sets the port value
	 * 
	 * @param port - the port value you wish to set
	 */
	public void setPort(int port) {
		if(port<=65535&&port>=1)
			this.port=port; 
		else
			xmlError=true; // if the value is not a valid port range, set error true
	}
	
	/**
	 * returns the port value
	 * 
	 * @return int
	 */
	public int getPort() {
		return port;
	}
	
	/**
	 * returns if a password is required on the server
	 * 
	 * @return boolean
	 */
	public boolean passwordRequired() {
		return passwordRequired;
	}
	
	/**
	 * sets if the password is required
	 * 
	 * @param value -- 0 for false, 1 for true, and anything else to cause an error
	 */
	public void setPasswordRequired(int value) {
		switch(value) {
		case 0:
			passwordRequired=false;
			break;
		case 1:
			passwordRequired=true;
			break;
		default:
			xmlError=true;
			break;
		}
	}
	
	/**
	 * sets if the image folder has been created
	 * 
	 * @param value -- 0 for false, 1 for true, and anything else to cause an error
	 */
	public void setImagesFolderCreated(int value) {
		switch(value) {
		case 0:
			imagesFolderExistsSet=true;
			imagesFolderExists=false;
			break;
		case 1:
			imagesFolderExistsSet = true;
			imagesFolderExists=true;
			break;
		default:
			xmlError=true;
			break;
		}
	}
	
	/**
	 * returns if the image folder has been created
	 * 
	 * @return boolean
	 */
	public boolean imageFolderCreated() {
		return imagesFolderExists;
	}
	
	/**
	 * returns the ISBN access key
	 * 
	 * @return String
	 */
	public String getAccessKey() {
		return ISBNdbAccessKey;
	}
	
	/**
	 * Sets the ISBN access key
	 * 
	 * @param s -- the ISBNdb access key you wish to set
	 */
	public void setAccessKey(String s) {
		this.ISBNdbAccessKey=s;
		this.ISBNdbAccessKeySet=true;
	}
	
	/**
	 * sets if the server is in debug mode
	 * 
	 * @param value -- 0 for false, 1 for true, and anything else to cause an error
	 */
	public void setDebugMode(int value) {
		switch(value) {
		case 0:
			debugMode=false;
			break;
		case 1:
			debugMode=true;
			break;
		default:
			xmlError=true;
			break;
		}
	}
		
	/**
	 * returns if the server is in debug mode
	 * 
	 * @return boolean
	 */
	public boolean inDebugMode() {
		return debugMode;
	}
}
